package com.example.parking.service.impl;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.parking.dto.PayDTO;
import com.example.parking.dto.Result;
import com.example.parking.entity.CarInfo;
import com.example.parking.entity.Garage;
import com.example.parking.entity.Order;
import com.example.parking.entity.User;
import com.example.parking.mapper.CarInfoMapper;
import com.example.parking.mapper.GarageMapper;
import com.example.parking.mapper.OrderMapper;
import com.example.parking.mapper.UserMapper;
import com.example.parking.service.IGarageService;
import com.example.parking.service.IOrderService;
import com.example.parking.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;


@Slf4j
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Resource
    private IUserService userService;

    @Resource
    private CarInfoMapper carInfoMapper;

    @Resource
    private IGarageService garageService;

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private GarageMapper garageMapper;


    /**
     * 停车功能
     *
     * @param garageId
     * @param userId
     * @return
     */
    @Override
    public Result stop(Integer garageId, Integer userId) {
        //判断是否有进行中的订单
        Order orderById = orderMapper.getById(userId);
        if (orderById != null){
            if (orderById.getState().equals(0)){
                return Result.fail("您有进行中的订单");
            }
        }
        //获取当前时间
        DateTime now = DateTime.now();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String nowTime = dateFormat.format(now);
        //获取当前登录的用户信息
        User user = userService.getById(userId);
        //获取当前登录用户的车辆信息
        CarInfo carInfo = carInfoMapper.getByLogin(userId);
        if (carInfo.getCarNum().isEmpty()){
            return Result.fail("您还未注册车辆信息");
        }
        //获取车位信息
        Garage garage = garageService.getById(garageId);
        Order order = new Order();
        //存储订单信息
        order.setGarageId(garageId);//车位id
        order.setUserId(userId);
        order.setUsername(user.getUsername());
        order.setPhone(user.getPhone());
        order.setCarNum(carInfo.getCarNum());//车牌号
        order.setLocation(garage.getLocation());//车位位置
        order.setAmount(BigDecimal.valueOf(0));//金额
        order.setBeginTime(nowTime);//开始时间
        order.setEndTime(nowTime);//结束时间(停车结束时更新)
        order.setState(0);//进行中的订单
        //保存订单对象
        orderMapper.insert(order);
        //将garageId的车位的状态改为使用中 赋1
        UpdateWrapper<Garage> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("garage_id",garageId);
        updateWrapper.set("state",1);
        garageService.update(null,updateWrapper);
        return Result.success();
    }


    /**
     * 结算功能-结束停车计费
     * @param garageId
     * @param userId
     * @return
     */
    @Override
    public Result pay(Integer garageId, Integer userId) {
        //用户点击结算 按车位金额计算价格
        //获取车位的信息(金额)
        Garage garage = garageService.getById(garageId);
        //车位的单价
        BigDecimal price = garage.getPrice();
        //TODO 计算停车的时长，按小时百分比计费
        //获取当前时间-结束时间
        DateTime now = DateTime.now();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String nowTime = dateFormat.format(now);
        //查询出当前进行中的订单
        Order order = orderMapper.getById(userId);
        //将当前时间设置为订单结束时间(结算失败时间不影响)
        order.setEndTime(nowTime);
        //订单开始的时间
        LocalDateTime startDateTime = LocalDateTime.parse(order.getBeginTime(),DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        //订单结束的时间
        LocalDateTime endDateTime = LocalDateTime.parse(order.getEndTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        //计算两个时间的差值
        Duration duration = Duration.between(startDateTime, endDateTime);
        //计算毫秒数
        BigDecimal decimal = new BigDecimal(duration.toMillis());
        //计算小时 精确两位小数
        BigDecimal hours = decimal.divide(BigDecimal.valueOf(3600000),2,BigDecimal.ROUND_UP);
        //TODO 如果停车时间低于一小时
        BigDecimal start = new BigDecimal(1);//起步价 = 1小时车位费
        PayDTO payDTO = new PayDTO();
        if(hours.compareTo(start) == -1){
            //缴费金额就是最低单价/h
            order.setAmount(price);
            User user = userService.getById(userId);
            //缴费金额 > 账户余额 返回1
            if (price.compareTo(user.getBalance()) == 1) {
                return Result.fail("您账户余额不足,请联系管理员进行充值");
            }
            //进行账户的扣款-缴费成功
            BigDecimal newBalance = user.getBalance().subtract(price);
            user.setBalance(newBalance);
            //扣款成功后的更新操作
            upUserAndOrder(user,order,garage);
            //返回停车的时长 + 缴费金额
            payDTO.setHours(hours);
            payDTO.setAmount(price);
        }else {
            //TODO 超过1h(正常的结算价)
            // 计算停车费金额 单价 * 时长
            BigDecimal money = price.multiply(hours).setScale(2);
            order.setAmount(money);
            //查询用户账户余额,小于价格提醒充值,结算失败
            User user = userService.getById(userId);
            //缴费金额 > 账户余额 返回1
            if (money.compareTo(user.getBalance()) == 1) {
                return Result.fail("您账户余额不足,请联系管理员进行充值");
            }
            //进行账户的扣款-缴费成功
            BigDecimal newBalance = user.getBalance().subtract(money);
            user.setBalance(newBalance);
            //扣款成功后的更新操作
            upUserAndOrder(user,order,garage);
            //返回停车的时长 + 缴费金额
            payDTO.setHours(hours);
            payDTO.setAmount(money);
        }
        //返回停车时长 + 缴费金额
        return Result.successData(payDTO);
    }

    //扣款后更新用户的方法
    public Result upUserAndOrder(User user,Order order,Garage garage){
        userMapper.updateById(user);//更新用户
        //订单状态修改为1(结束)
        order.setState(1);
        orderMapper.updateById(order);//更新订单
        //车位状态修改为0(空闲状态)
        garage.setState(String.valueOf(0));
        garageMapper.updateById(garage);//更新车位
        return Result.success();
    }
}
